﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ZoneLinePacking.Common {

    /// <summary>
    /// 奇瑞校验码
    /// </summary>
    public class CheckCodeCalculator_T1N {

        private static readonly Dictionary<char, int> _symbolToValue = new Dictionary<char, int>
        {
            {'0', 0}, {'1', 1}, {'2', 2}, {'3', 3}, {'4', 4}, {'5', 5}, {'6', 6}, {'7', 7}, {'8', 8}, {'9', 9},
            {'A', 10}, {'B', 11}, {'C', 12}, {'D', 13}, {'E', 14}, {'F', 15}, {'G', 16}, {'H', 17}, {'I', 18}, {'J', 19}, {'K', 20},
            {'L', 21}, {'M', 22}, {'N', 23}, {'O', 24}, {'P', 25}, {'Q', 26}, {'R', 27}, {'S', 28}, {'T', 29}, {'U', 30}, {'V', 31},
            {'W', 32}, {'X', 33}, {'Y', 34}, {'Z', 35}
        };

        // 数值→字符反向映射表（用于根据余数获取校验码）
        private static readonly Dictionary<int, char> _valueToSymbol = new Dictionary<int, char>();

        // 静态构造函数：初始化反向映射表
        static CheckCodeCalculator_T1N() {
            foreach (var item in _symbolToValue) {
                _valueToSymbol[item.Value] = item.Key;
            }
        }

        /// <summary>
        /// 计算条码校验码
        /// </summary>
        /// <param name="barcodePrefix">条码字符串（支持大小写字母，会自动转为大写处理）</param>
        /// <returns>校验码字符（大写）</returns>
        /// <exception cref="ArgumentNullException">输入为null时抛出</exception>
        /// <exception cref="ArgumentException">输入长度不为15或包含无效字符时抛出</exception>
        public static char Calculate(string barcodePrefix)
        {
            // 验证输入不为null
            if (barcodePrefix == null)
                throw new ArgumentNullException(nameof(barcodePrefix), "条码不能为null");

            // 验证长度为15
            if (barcodePrefix.Length < 15)
                throw new ArgumentException("条码长度至少位15", nameof(barcodePrefix));

            // 转换为大写（统一处理大小写）
            string upperPrefix = barcodePrefix.ToUpperInvariant();

            int total = 0;
            foreach (char c in upperPrefix)
            {
                // 验证字符是否有效
                if (!_symbolToValue.ContainsKey(c))
                    throw new ArgumentException($"条码包含无效字符：{c}", nameof(barcodePrefix));

                // 累加字符对应的数值
                total += _symbolToValue[c];
            }

            // 计算总和对36的余数
            int remainder = total % 36;

            // 根据余数获取校验码
            return _valueToSymbol[remainder];
        }

    }


}
